package com.ruoyi.business.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.github.pagehelper.Page;
import com.ruoyi.business.domain.DefinitionNode;
import com.ruoyi.business.domain.HistoricActivity;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.ServiceItemMapper;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.AddressUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.CarPackageAuditMapper;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 审核列Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-07-20
 */
@Service
public class CarPackageAuditServiceImpl implements ICarPackageAuditService 
{
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;

    @Autowired
    private IProcessService processService;

    @Autowired
    private ServiceItemMapper serviceItemMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private IDefinitionNodeService definitionNodeService;
    /**
     * 查询审核列
     * 
     * @param id 审核列ID
     * @return 审核列
     */
    @Override
    public CarPackageAudit selectCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.selectCarPackageAuditById(id);
    }

    /**
     * 查询审核列列表
     * 
     * @param carPackageAudit 审核列
     * @return 审核列
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit)
    {
        List<CarPackageAudit> carPackageAudits = carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
        List<CarPackageAudit> carPack = new ArrayList<>();
        for (CarPackageAudit audit : carPackageAudits) {

            audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));
            Task task = processService.selectTeakByInstanceId(audit.getInstanceId());
            if (task != null) {
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
            }else {
                audit.setTaskName("任务结束");
            }
            if (audit.getCreateBy().equals(ShiroUtils.getUserId().toString())){
                carPack.add(audit);
            }
        }
        return carPack;
    }

    /**
     * 新增审核列
     * 
     * @param carPackageAudit 审核列
     * @return 结果
     */
    @Override
    public int insertCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        carPackageAudit.setCreateTime(DateUtils.getNowDate());
        return carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    /**
     * 修改审核列
     * 
     * @param carPackageAudit 审核列
     * @return 结果
     */
    @Override
    public int updateCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        return carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 删除审核列对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditByIds(String ids)
    {
        return carPackageAuditMapper.deleteCarPackageAuditByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除审核列信息
     * 
     * @param id 审核列ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.deleteCarPackageAuditById(id);
    }

    @Override
    @Transactional
    public void cancelApply(Long instanceId) {
        /**
         * * 1.根据流程实例ID查询流程实例对象
         * 2.通过流程实例获取业务key
         * 3.根据业务key查询审核对象，更新状态为撤销状态,审核人设置为空
         * 4.获取服务项,更新审核状态为初始化
         * 5.删除流程实例
         */
        ProcessInstance instance  = processService.selectRunTimeServiceByiNstanceId(instanceId);
        String businessKey = instance.getBusinessKey();
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(Long.valueOf(businessKey));
        carPackageAudit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAudit.setAuditors("");
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
        ServiceItem serviceItem = JSON.parseObject(carPackageAudit.getServiceItemInfo(),ServiceItem.class);
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        serviceItemMapper.updateServiceItemByServiceItem(serviceItem);
        processService.deleteByInstanceId(instanceId);
    }

    @Override
    @Transactional
    public List<CarPackageAudit> todoPageList(CarPackageAudit carPackageAudit) {
        //获取任务的总数
        long count = processService.getTodoPageCount(CarPackageAudit.DEFINITION_KEY,ShiroUtils.getUserId().toString());
        if (count>0) {
            PageDomain pageDomain = TableSupport.buildPageRequest();
            int pageNum = pageDomain.getPageNum();
            int pageSize = pageDomain.getPageSize();
            //查询当前待办任务的集合
            List<Task> taskList = processService.selectTodoTaskList(CarPackageAudit.DEFINITION_KEY,ShiroUtils.getUserId().toString()
                    ,(pageNum-1) * pageSize,
                    pageSize);
            List<CarPackageAudit> list = new ArrayList<>();
            CarPackageAudit audit ;
            for (Task task : taskList) {
                ProcessInstance instance = processService.getProcessInstanceById(task.getProcessInstanceId());
                String businessKey = instance.getBusinessKey();
                 audit = carPackageAuditMapper.selectCarPackageAuditById(Long.valueOf(businessKey));
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));
                list.add(audit);
            }
            Page<CarPackageAudit> pageList = new Page<>();
            pageList.setPageNum(pageNum);
            pageList.setPageSize(pageSize);
            pageList.addAll(list);
            return pageList;
        }else {
            return Collections.emptyList();
        }
    }

    @Override
    @Transactional
    public void complete(String taskId, String auditStatus, String comment) {
        /**
         * 1.根据任务Id查询任务对象
         * 2.给任务添加批注,设置流程变量,认领任务，完成任务
         * 3.查询流程实例下一个任务.
         * 4.判断是否有下一个任务.
         *   4.1如果有下一个任务
         *      判断审核通过还是审核拒绝
         *      4.1.1如果是审核通过
         *           根据任务的key查询对应的审核人集合
         *           给任务设置候选人
         *      4.1.2如果是审核拒绝
         *           查询任务的发起人.
         *           给任务设置候选人(发起人)
         *           设置审核对象的状态为（拒绝）
         *      更新审核对象
         *   4.2如果没有下一个任务(流程已经结束,审核通过)
         *      修改审核对象的状态
         *      修改养修明细项的状态
         */

        Task task = processService.getTaskByTaskId(taskId);
        boolean auditstatusBoolean = BooleanUtils.toBoolean(auditStatus);
        String commentStr = auditstatusBoolean ? "[同意]" : "[拒绝]";
        //查询流程实例id
        ProcessInstance instance = processService.getProcessInstanceById(task.getProcessInstanceId());
        if (!StringUtils.isEmpty(commentStr)){
            commentStr += comment;
        }
        //给任务添加批注,设置流程变量,认领任务，完成任务
        processService.claimAndComplateTask(task,ShiroUtils.getUserId().toString(),auditstatusBoolean,commentStr);
        Task nextTask = processService.selectTeakByInstanceId(task.getProcessInstanceId());
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(Long.parseLong(instance.getBusinessKey()));
        if (nextTask != null) {
            List<String> auditList = new ArrayList<>();
            if (auditstatusBoolean) {
                //根据任务的key查询对应的审核人集合
                String taskDefinitionKey = nextTask.getTaskDefinitionKey();
                List<SysUser> userList = definitionNodeService.queryUserByDeFinitionKey(taskDefinitionKey);
                for (SysUser user : userList) {
                    //给任务设置候选人
                    processService.addUser(nextTask,user.getUserId());
                    auditList.add(user.getUserName());
                }
            }else {
                String userId = audit.getCreateBy();
                processService.addUser(nextTask,Long.parseLong(userId));
                auditList.add(audit.getCreateByName());
                audit.setStatus(CarPackageAudit.STATUS_REJECT);
            }
            audit.setAuditors(JSON.toJSONString(auditList));
            carPackageAuditMapper.updateCarPackageAudit(audit);
        }else {
            ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class);
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_APPROVED);
            serviceItemMapper.updateServiceItemByServiceItem(serviceItem);
            audit.setStatus(CarPackageAudit.STATUS_PASS);
            audit.setAuditors("");
            audit.setServiceItemInfo(JSON.toJSONString(serviceItem));
            carPackageAuditMapper.updateCarPackageAudit(audit);
        }
    }

    /**
     * 修改表单(更新养修服务表和快照表)
     * @param carPackageAuditId
     * @param serviceItem
     * @return
     */
    @Override
    @Transactional
    public int updateServiceItem(Long carPackageAuditId, ServiceItem serviceItem) {
        try {
            serviceItemMapper.updateServiceItemByServiceItem(serviceItem);
            CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
            audit.setServiceItemInfo(JSON.toJSONString(serviceItem));
            carPackageAuditMapper.updateCarPackageAudit(audit);
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 重新申请
     * @param taskId
     * @param carPackageAuditId
     * @return
     */
    @Override
    @Transactional
    public int reply(String taskId, Long carPackageAuditId) {
        //1.根据任务ID查询任务对象
        Task task = processService.getTaskByTaskId(taskId);
        //2.重新设置流程变量
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
        ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class);
        processService.setVariable(taskId,"money",serviceItem.getDiscountPrice().longValue());
        //3.领取任务并完成任务
        processService.claimAndComplateTask(task,ShiroUtils.getUserId().toString(),true,"重新申请");
        //4.完成任务后查询流程实例的下一个任务.
        Task nextTask = processService.getTaskByInstanceId(task.getProcessInstanceId());
        ProcessInstance instance = processService.getProcessInstanceById(task.getProcessInstanceId());
        //5.需要指定下一个任务的候选人
        List<String> auditors = new ArrayList<>();
        String taskDefinitionKey = nextTask.getTaskDefinitionKey();
        List<SysUser> userList = definitionNodeService.queryUserByDeFinitionKey(taskDefinitionKey);
        for (SysUser user : userList) {
            processService.addUser(nextTask,user.getUserId());
            auditors.add(user.getUserName());
        }
        //6.更新审核对象CarPackageAudit
        audit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        audit.setAuditors(JSON.toJSONString(auditors));
        carPackageAuditMapper.updateCarPackageAudit(audit);
        return 1;
    }

    /**
     * 我的已办
     * @param carPackageAudit
     * @return
     */
    @Override
    public List<CarPackageAudit> donePageList(CarPackageAudit carPackageAudit) {
        //查询已办任务总数
        long count = processService.selectDoneTaskCount(CarPackageAudit.DEFINITION_KEY,ShiroUtils.getUserId().toString());
        if(count > 0){
            PageDomain pageDomain = TableSupport.getPageDomain();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            Integer beginIndex = (pageNum - 1) * pageSize;
            List<HistoricTaskInstance> taskInstances = processService.selectDoneList(CarPackageAudit.DEFINITION_KEY,ShiroUtils.getUserId().toString(),beginIndex,pageSize);
            //3.遍历待办任务,查询对应的CarPackAgeAudit
            List<CarPackageAudit> auditList = new ArrayList<>();
            CarPackageAudit audit;
            for (HistoricTaskInstance taskInstance : taskInstances) {
                HistoricProcessInstance historicProcessInstance
                        = processService.getHistoricProcessInstanceById(taskInstance.getProcessInstanceId());
                String businessKey = historicProcessInstance.getBusinessKey();
                audit = carPackageAuditMapper.selectCarPackageAuditById(Long.valueOf(businessKey));
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));
                audit.setTaskName(taskInstance.getName());
                audit.setFinishTime(taskInstance.getEndTime());
                audit.setTaskId(taskInstance.getId());
                auditList.add(audit);
            }
            Page<CarPackageAudit> list = new Page<>();
            list.setTotal(count);
            list.setPageSize(pageSize);
            list.setPageNum(pageNum);
            list.addAll(auditList);
            return list;
        }else {
            return Collections.EMPTY_LIST;
        }
    }

    /**
     * 历史审核列表
     * @param instanceId
     * @return
     */
    @Override
    public List<HistoricActivity> selectHistoryListByInstanceId(String instanceId) {
        //查询集合
        List<HistoricActivityInstance> instanceList = processService.selectHistoryTaskList(instanceId);
        List<HistoricActivity> historicActivityList = new ArrayList<>();
        for (HistoricActivityInstance instance : instanceList) {
            HistoricActivity historicActivity = new HistoricActivity();
            //拷贝属性
            BeanUtils.copyProperties(instance,historicActivity);
            historicActivity.setComment(processService.getTaskComment(instance.getTaskId()));
            String assignee = instance.getAssignee();
            if(StringUtils.isNotEmpty(assignee)){
                SysUser sysUser = sysUserMapper.selectUserById(Long.valueOf(assignee));
                if(sysUser != null){
                    //设置审核人姓名
                    historicActivity.setAssigneeName(sysUser.getUserName());
                }
            }
            historicActivityList.add(historicActivity);
        }
        return historicActivityList;
    }
}
